/*
Hermes Core: General Purpose Mobile Agent Platform
Copyright (C) 2006 UNICAM - Università degli Studi di Camerino

Group leaders: Flavio Corradini and Emanuela Merelli

Developers: Ezio Bartocci, Diego Bonura, Rosario Culmone,
Davide Lorenzoli, Leonardo Mariani, Francesca Piersigilli, 
Lorenzo Scortichini, Leonardo Vito.

GNU Lesser Public License

This library is free software; you can redistribute it 
and/or modify it under the terms of the GNU Lesser General 
Public License as published by the Free Software Foundation, 
version 2.1 of the License.

This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU Library General Public License for more details.

You should have received a copy of the GNU Library General Public 
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

Emanuela Merelli
Dipartimento di Matematica ed Informatica
Università di Camerino
via Madonna delle Carceri, 62032 Camerino, Italy
E.Mail: emanuela.merelli@unicam.it
*/
package hermesV2;

import hermesV2.util.SmartPack;

import java.io.IOException;
import java.io.Serializable;


/**
 * It represents the object exchanged between different Place. It is used only
 * by core components and it could contain service messages or  agent
 * messages.
 *
 * @author Diego Bonura
 */
public class Envelope<T extends Object> implements Serializable {
    /**
	 * 
	 */
	private static final long serialVersionUID = 5341692322389859094L;

	/** The envolope contains an Agent */
    public static final int AGENT_ENTER = 0;

    /** The envelope contains the request of a class file. */
    public static final int CLASS_REQUEST = 1;

    /** The place did not find the class request. */
    public static final int CLASS_NOTFOUND = 2;

    /** The envelope contains a class file. */
    public static final int CLASS_ENTER = 3;

    /** The envelope contains a general message */
    public static final int GENERAL_MESSAGE = 4;

    /** Reception is ok. */
    public static final int RECEPTION_OK = 5;

    /** Reception is ko, something went wrong. */
    public static final int RECEPTION_KO = 6;

    /** Request the update of the Borns Table of the Id Manager component. */
    public static final int UPDATED_ADDRESS = 7;

    /** Request the current address of a specific agent */
    public static final int ADDRESS_REQUEST = 8;

    /** The envelope contains the current location of a specific agnet */
    public static final int ADDRESS_ENTER = 9;

    /** The envelope contains a message to an User agent. */
    public static final int MESSAGE_TO_USERAGENT = 10;

    /** The envelope contains a message to a Service agent. */
    public static final int MESSAGE_TO_SERVICEAGENT = 11;

    /**
     * Request to erase the agent Identificator from the bornsAgnet table of a
     * remote place
     */
    public static final int ADDRESS_ERASE_REQUEST = 12;

    /** The type of the envelope. */
    private int type;

    /** It is the container of the real object transported by the envelope. */
    private SmartPack<T> smartPack;

    /** The sender place address. */
    private PlaceAddress senderPlaceAddress;

    /** The receiver place address. */
    private PlaceAddress receiverPlaceAddress;

    /**
     * Creates a new Envelope object.
     *
     * @param type type of the envelope.
     * @param obj the object contained in the envelope.
     * @param senderPlaceAddress the sender place address.
     * @param receiverPlaceAddress the receiver place address.
     */
    public Envelope(int type, T obj, PlaceAddress senderPlaceAddress, PlaceAddress receiverPlaceAddress) {
        this.smartPack = new SmartPack<T>(obj);
        this.type = type;
        this.senderPlaceAddress = senderPlaceAddress;
        this.receiverPlaceAddress = receiverPlaceAddress;
    }

    /**
     * Returns the object contained into the Envelope. It use the getObject ot
     * the SmartPack object that represents the real container of the object.
     *
     * @return the object trasported.
     *
     * @throws ClassNotFoundException it is not present the class to resolve
     *         the object.
     * @throws IOException something went wrong with the array of byte of the
     *         SmartPack object.
     */
    public Object getObject() throws ClassNotFoundException, IOException {
        Object o = null;

        try {
            o = this.smartPack.getObject();
        } catch (ClassNotFoundException cnfe) {
            throw cnfe;
        } catch (IOException io) {
            throw io;
        }

        return o;
    }

    /**
     * Return the container of the object.
     *
     * @return the container of the object.
     */
    public SmartPack<T> getSmartPack() {
        return smartPack;
    }

    /**
     * Returns the type of the envelope.
     *
     * @return the type of the envelope.
     */
    public int getType() {
        return type;
    }

    /**
     * Returns the sender PlaceAddress.
     *
     * @return the sender PlaceAddress.
     */
    public PlaceAddress getSenderPlaceAddress() {
        return senderPlaceAddress;
    }

    /**
     * Returns the receiver PlaceAddress.
     *
     * @return the receiver PlaceAddress.
     */
    public PlaceAddress getReceiverPlaceAddress() {
        return receiverPlaceAddress;
    }
    
    /**If I have to send a message to an android emulator, the sender ip should be 10.0.2.2, so that 
     * the emulator can send back messages. This method just change the sender ip of the message to 10.0.2.2*/
    public void switchSenderIPforAndroid(){
    	PlaceAddress switched = new PlaceAddress("10.0.2.2", senderPlaceAddress.getPort(), senderPlaceAddress.getPhoneNumber());
    	senderPlaceAddress = switched;
    }
    
  
    
}
